package com.ding.easycontroller.socket;

import com.ding.easycontroller.bean.ConsoleWork;
import com.ding.easycontroller.helper.EcSession;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;

import javax.script.ScriptEngine;
import java.io.IOException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

@Component
public class ConsoleWebSocketHandler implements WebSocketHandler {


    @Autowired
    private ConsoleWork consoleWork;

    @Autowired
    private ScriptEngine scriptEngine;

    private Map<String, Writer> writerMap = new HashMap<>();

    @Override
    public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {

        EcSession ecSession = new EcSession(webSocketSession);

        Writer writer = new Writer() {

            private StringBuilder builder = new StringBuilder();

            @Override
            public void write(char[] cbuf, int off, int len) throws IOException {
                builder.append(cbuf, off, len);
            }

            @Override
            public void flush() throws IOException {
                String s = builder.toString();
                builder.delete(0, builder.length());
                ecSession.send(s);
            }

            @Override
            public void close() throws IOException {

            }
        };
        consoleWork.addWriter(writer);
        writerMap.put(webSocketSession.getId(), writer);

    }

    @Override
    public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {

        try {
            String payload = (String) webSocketMessage.getPayload();
            JSONObject jsonObject = new JSONObject(payload);
            String type = jsonObject.getString("type");
            if (type != null) {
                if (type.equals("command")) {
                    String body = jsonObject.getString("body");
                    scriptEngine.eval(body);
                }
            }
        } catch (Exception e) {
            consoleWork.log(e.getMessage());
        }
    }


    @Override
    public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {

    }

    @Override
    public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
        Writer writer = writerMap.get(webSocketSession.getId());
        writerMap.remove(webSocketSession.getId());
        consoleWork.removeWriter(writer);
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }
}
